home *** CD-ROM | disk | FTP | other *** search
/ Aminet 3 / Aminet 3 - July 1994.iso / Aminet / misc / unix / tracker_4_3.lzh / tracker / Amiga / scroller.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-02-13  |  6.0 KB  |  224 lines

  1. /* amiga/scroller.c 
  2.     vi:se ts=3 sw=3:
  3.  */
  4.  
  5. /* $Id: scroller.c,v 1.5 1994/01/09 17:38:28 Espie Exp Espie $
  6.  * $Log: scroller.c,v $
  7.  * Revision 1.5  1994/01/09  17:38:28  Espie
  8.  * Generalized open.c.
  9.  *
  10.  * Revision 1.4  1994/01/09  04:49:18  Espie
  11.  * Stupid: forgot that a window font can very well be proportional.
  12.  * It's easier to rely on GfxBase->DefaultFont after all.
  13.  *
  14.  * Revision 1.3  1994/01/08  19:45:29  Espie
  15.  * Uncentralized event handling using event management functions.
  16.  *
  17.  * Revision 1.2  1994/01/08  04:00:52  Espie
  18.  * Handle own's clipping without Layers.
  19.  * Use dynamic colours/masks according to current screen.
  20.  * Added forbid_reopen to avoid dangling window.
  21.  *
  22.  */
  23.  
  24. /* The line scroller implemented as a window */
  25.  
  26. #include <assert.h>
  27. #include <stdio.h>
  28. #include <stdlib.h>
  29.  
  30. #include <intuition/screens.h>
  31. #include <graphics/text.h>
  32. #include <graphics/gfxmacros.h>
  33. #include <proto/intuition.h>
  34. #include <proto/exec.h>
  35. #include <proto/graphics.h>
  36. #include <graphics/gfxbase.h>
  37.  
  38. #include "defs.h"
  39. #include "extern.h"
  40. #include "amiga/amiga.h"
  41. #include "prefs.h"
  42.  
  43. ID("$Id: scroller.c,v 1.5 1994/01/09 17:38:28 Espie Exp Espie $")
  44.  
  45. LOCAL void init_scroller(void);
  46. LOCAL void (*INIT)(void) = init_scroller;
  47. LOCAL boolean forbid_reopen = FALSE;
  48. LOCAL void handle_scroller(GENERIC nothing);
  49.  
  50. XT struct IntuitionBase *IntuitionBase;
  51. XT struct GfxBase *GfxBase;
  52.  
  53. XT struct Window *ui_win;
  54.  
  55. /* our window */
  56. LOCAL struct Window *scroll_win = 0;
  57. LOCAL struct TextFont *font;
  58.    
  59.  
  60. /* to build up write masks */
  61. LOCAL ULONG text, highlight, background;
  62.  
  63.  
  64. LOCAL void close_scroller()    
  65.    {
  66.    if (scroll_win)
  67.       {
  68.       remove_signal_handler(scroll_win->UserPort->mp_SigBit);
  69.       CloseWindow(scroll_win);
  70.       }
  71.    scroll_win = 0;               /* and get ready for reopen */
  72.    }
  73.  
  74. LOCAL void really_close_scroller()
  75.    {
  76.    forbid_reopen = TRUE;
  77.    close_scroller();
  78.    }
  79.  
  80. /* graphic niceties: draw vertical lines at the right separation points
  81.  * all the way between y1 and the bottom
  82.  */
  83. LOCAL void separation_lines(int y1)
  84.    {
  85.    int x, xs, i, c;
  86.    
  87.    xs = font->tf_XSize;
  88.    
  89.    SetWrMsk(scroll_win->RPort, background | highlight);  
  90.    SetAPen(scroll_win->RPort, highlight);   
  91.    x = scroll_win->BorderLeft;
  92.    for (i = 1; i < 4; i++)
  93.       {
  94.       x += 14 * xs;     /* 14 chars per column */
  95.       c = x - xs/2;
  96.       if (c >= scroll_win->Width - scroll_win->BorderRight -1)
  97.          break;
  98.       Move(scroll_win->RPort, x - xs/2, y1);
  99.       Draw(scroll_win->RPort, x - xs/2, scroll_win->Height - scroll_win->BorderBottom - 1);
  100.       }
  101.    }
  102.    
  103. LOCAL void init_scroller()
  104.    {
  105.    struct DrawInfo *dr;
  106.    
  107.    at_end(really_close_scroller);
  108.       /* default text, background, etc */
  109.    text = 1;
  110.    background = 0;
  111.    highlight = 7;
  112.    dr = GetScreenDrawInfo(ui_win->WScreen);
  113.    if (dr)
  114.       {
  115.       if (dr->dri_Version >= 1)  /* for V 2.04 */
  116.          {
  117.          text = dr->dri_Pens[TEXTPEN];
  118.          background = dr->dri_Pens[BACKGROUNDPEN];
  119.          highlight = dr->dri_Pens[SHINEPEN];
  120.          }
  121.       FreeScreenDrawInfo(ui_win->WScreen, dr);
  122.       }
  123.    }
  124.    
  125.  
  126. LOCAL void open_scroller()
  127.    {
  128.    INIT_ONCE;
  129.    font = GfxBase->DefaultFont;
  130.    scroll_win = OpenWindowTags(NULL,
  131.       WA_Title, "Scroll",
  132.       WA_DepthGadget, TRUE,
  133.       WA_SmartRefresh, TRUE,
  134.       WA_DragBar, TRUE,
  135.       WA_SizeGadget, TRUE,
  136.       WA_CloseGadget, TRUE,
  137.       WA_InnerWidth, font->tf_XSize * 60, /* 60 = 14 * 4 + some margin */
  138.       WA_InnerHeight, font->tf_YSize * 15,
  139.       WA_MinWidth, 15 * font->tf_XSize,
  140.       WA_MaxWidth, ~0,           /* need some room for the size gadget */
  141.       WA_MinHeight, 2 * ui_win->BorderTop,   
  142.       WA_MaxHeight, ~0,
  143.       WA_AutoAdjust, TRUE,
  144.       WA_NoCareRefresh, TRUE,
  145.       WA_IDCMP, IDCMP_NEWSIZE | IDCMP_CLOSEWINDOW);
  146.  
  147.    if (!scroll_win)
  148.       end_all(0);
  149.       
  150.    SetFont(scroll_win->RPort, font);
  151.    install_signal_handler(scroll_win->UserPort->mp_SigBit, handle_scroller, 0);
  152.    separation_lines(scroll_win->BorderTop);
  153.    }
  154.  
  155.  
  156.  
  157. LOCAL void handle_scroller(GENERIC nothing)   
  158.    {
  159.    struct IntuiMessage *msg;
  160.    while (scroll_win && (msg = GetMsg(scroll_win->UserPort)))
  161.       switch(msg->Class)
  162.          {
  163.       case IDCMP_NEWSIZE:
  164.          ReplyMsg(msg);
  165.          separation_lines(scroll_win->BorderTop);  /* redraw lines where applicable */
  166.          break;
  167.       case IDCMP_SIZEVERIFY:
  168.          ReplyMsg(msg);
  169.          break;
  170.       case IDCMP_CLOSEWINDOW:
  171.          ReplyMsg(msg);
  172.          close_scroller();
  173.          set_pref_scalar(PREF_SHOW, FALSE);
  174.          break;
  175.       default:
  176.          ReplyMsg(msg);
  177.          }
  178.    }
  179.  
  180. void add_scroller(char *s)
  181.    {
  182.    int max_length;
  183.  
  184.    if (forbid_reopen)
  185.       return;
  186.    if (!scroll_win)
  187.       open_scroller();
  188.       
  189.       /* critical section for size changes */
  190.    ModifyIDCMP(scroll_win, scroll_win->IDCMPFlags | IDCMP_SIZEVERIFY);
  191.    handle_scroller(0);   /* handle size problems first */
  192.  
  193.    if (!scroll_win)     /* window may have closed on us... */
  194.       return;
  195.  
  196.       /* add the characters */
  197.    SetDrMd(scroll_win->RPort, JAM1);
  198.    SetWrMsk(scroll_win->RPort, background | text);
  199.    SetAPen(scroll_win->RPort, text);
  200.    Move(scroll_win->RPort, scroll_win->BorderLeft, 
  201.       scroll_win->Height - scroll_win->BorderBottom 
  202.     - font->tf_YSize + font->tf_Baseline);
  203.    max_length = scroll_win->Width - scroll_win->BorderLeft - scroll_win->BorderRight;
  204.    max_length /= font->tf_XSize;
  205.    if (max_length > 14 * 4 - 1)
  206.       max_length = 14 * 4 -1;    /* line length = 14 * 4 - 1 */
  207.    Text(scroll_win->RPort, s, max_length);
  208.    
  209.       /* add the separation lines */
  210.    separation_lines(scroll_win->Height - scroll_win->BorderBottom 
  211.     - font->tf_YSize);
  212.       
  213.       /* and scroll *JUST* the characters */
  214.    SetWrMsk(scroll_win->RPort, 1);
  215.    ScrollRaster(scroll_win->RPort, 0, font->tf_YSize, 
  216.                   scroll_win->BorderLeft, scroll_win->BorderTop, 
  217.                   scroll_win->Width - scroll_win->BorderRight - 1,
  218.                   scroll_win->Height - scroll_win->BorderBottom - 1);
  219.    
  220.       /* end of critical section: allow resize again */
  221.    ModifyIDCMP(scroll_win, scroll_win->IDCMPFlags & ~IDCMP_SIZEVERIFY);
  222.    handle_scroller(0); 
  223.    }
  224.